//
//  ParserToGML.java
//  TopoManipApplet
//
//  Created by Thibaud PIQUET on 09/04/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

package src.convertisseur;
import java.util.*;
import java.io.*;
import org.jdom.*;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import org.xml.sax.SAXException;
import java.net.*;

/**
 *
 * @author Thibaud PIQUET
 */
public class ParserToGML implements Runnable{
	
    File ftp; // File to parse
	File fileOut; // File to create
    Writer fw; // File Writer
    BufferedWriter bw; // Buffer Writer
    String line;
    String chaine;
    String[] res;
	
    public ParserToGML(File file, File fileOUT) throws IOException {
        this.ftp = file;
		this.fileOut = fileOUT;
        this.fw = new FileWriter(this.fileOut);
        this.bw = new BufferedWriter(this.fw);
    }
	
	public void run() {
		try {
			this.parseToGML();
		}
		catch (Exception e) {
			e.printStackTrace();
			Resume result = Resume.getInstance();
			result.add("ParserToGML","procedure run had some problems : "+e);
		}
	}
    
	public void parseToGML() throws IOException {
		
		Element domain;
		Element topology;
		Element nodes;
		Element links;

		Resume result = Resume.getInstance();

		try {
			
            // **********************************************************
            // Default values for RIG if there aren't in the XML file
            // -- Edge
            // linkType : 1 correspond to simplex
            // bandwidth : 1Mb
            // metric : 100
            // **********************************************************
			
			/************************************************************ Loading default values *************************************************************/
			InputStream inDefaultValues = getClass().getResourceAsStream("/resources/configuration.xml");
			
			org.jdom.input.SAXBuilder builderConfig = new org.jdom.input.SAXBuilder();
            builderConfig.setIgnoringElementContentWhitespace(true);
            org.jdom.Document documentDefaultValues = builderConfig.build(inDefaultValues);
			
			Element defaultValues = documentDefaultValues.getRootElement();
			
			String defaultValue_Link_bandwidth="", defaultValue_Link_metric="",defaultValue_Link_linkType="";
			
			List listOfFormats = defaultValues.getChildren();
			Iterator ilistOfFormats = listOfFormats.iterator();
			while(ilistOfFormats.hasNext()){
				Element currentChildOfDefaultValues = (Element)ilistOfFormats.next();
				
				if(currentChildOfDefaultValues.toString().equals("[Element: <format/>]")) {
					
					if(currentChildOfDefaultValues.getAttributeValue("name").equals("GML")){
						
						List listOfDefaultValuesOfFormat = currentChildOfDefaultValues.getChildren();
						Iterator ilistOfDefaultValuesOfFormat = listOfDefaultValuesOfFormat.iterator();
						while(ilistOfDefaultValuesOfFormat.hasNext()){
							Element currentChildOfFormat = (Element)ilistOfDefaultValuesOfFormat.next();
													
							if(currentChildOfFormat.toString().equals("[Element: <link/>]")){
								
								List listOfChildOfNode = currentChildOfFormat.getChildren();
								Iterator ilistOfChildOfNode = listOfChildOfNode.iterator();
								while(ilistOfChildOfNode.hasNext()){
									Element currentUnit = (Element)ilistOfChildOfNode.next();
									
									if(currentUnit.toString().equals("[Element: <unit/>]")){
																					
										if(currentUnit.getAttributeValue("type").equals("bandwidth")){
											defaultValue_Link_bandwidth=currentUnit.getAttributeValue("value");
										}
										if(currentUnit.getAttributeValue("type").equals("metric")){
											defaultValue_Link_metric=currentUnit.getAttributeValue("value");
										}
										if(currentUnit.getAttributeValue("type").equals("linkType")){
											defaultValue_Link_linkType=currentUnit.getAttributeValue("value");
										}											
									}
								}
							}
						}
					}
				}
			}				
			/*************************************************************************************************************************************************/
			
            org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
            builder.setIgnoringElementContentWhitespace(true);
            org.jdom.Document document = builder.build(ftp);
			
            domain = document.getRootElement();
			
            /* Test to know domain's sons */
            boolean BoolTopology = false;
			
            List domainChildren = domain.getChildren();
            Iterator idomainChildren = domainChildren.iterator();
            while(idomainChildren.hasNext()) {
                Element currentChild = (Element)idomainChildren.next();
                if(currentChild.toString().equals("[Element: <topology/>]")) { BoolTopology=true; }
            }
			
            if(BoolTopology==true){
                topology = domain.getChild("topology");
                nodes = topology.getChild("nodes");
                links = topology.getChild("links");
				
                bw.write("graph [");
                bw.newLine();
                
                String idNode="", nameNode="", position="", image="", outlineColor="", forme="", fillColor="";
                Double x=0.0, y=0.0, z=0.0, w=0.0, h=0.0, d=0.0;
				
                List listOfNode = nodes.getChildren();
                Iterator ilistOfNode = listOfNode.iterator();
                while(ilistOfNode.hasNext()){
                    Element currentNode = (Element)ilistOfNode.next();
					
                    List listOfChildOfNode = currentNode.getChildren();
                    Iterator ilistOfChildOfNode = listOfChildOfNode.iterator();
                    while(ilistOfChildOfNode.hasNext()){
                        Element currentChildNode = (Element)ilistOfChildOfNode.next();
						
                        if(currentChildNode.toString().equals("[Element: <location/>]")){
                            List listOfAttributesOfLocation = currentChildNode.getAttributes();
                            Iterator ilistOfAttributesOfLocation = listOfAttributesOfLocation.iterator();
                            while(ilistOfAttributesOfLocation.hasNext()){
                                Attribute currentAttributeLocation = (Attribute)ilistOfAttributesOfLocation.next();
								
                                if(currentAttributeLocation.getName().equals("x")){
                                    x=Double.parseDouble(currentAttributeLocation.getValue());
                                }
								
                                if(currentAttributeLocation.getName().equals("y")){
                                    y=Double.parseDouble(currentAttributeLocation.getValue());
                                }
								
                                if(currentAttributeLocation.getName().equals("z")){
                                    z=Double.parseDouble(currentAttributeLocation.getValue());
                                }
								
                                if(currentAttributeLocation.getName().equals("w")){
                                    w=Double.parseDouble(currentAttributeLocation.getValue());
                                }
								
                                if(currentAttributeLocation.getName().equals("h")){
                                    h=Double.parseDouble(currentAttributeLocation.getValue());
                                }
								
                                if(currentAttributeLocation.getName().equals("d")){
                                    d=Double.parseDouble(currentAttributeLocation.getValue());
                                }
								
                                /* case if there is location with latitude & longitude and no x & y coordonates */
                                if(currentAttributeLocation.getName().equals("latitude")){
                                    if(x==0.0){
                                        x=Double.parseDouble(currentAttributeLocation.getValue());
                                    }
                                }
								
                                if(currentAttributeLocation.getName().equals("longitude")){
                                    if(y==0.0){
                                        y=Double.parseDouble(currentAttributeLocation.getValue());
                                    }
                                }
                            }
                        }
						
                        if(currentChildNode.toString().equals("[Element: <description/>]")){
                            List listOfAttributesOfDescription = currentChildNode.getAttributes();
                            Iterator ilistOfAttributesOfDescription = listOfAttributesOfDescription.iterator();
                            while(ilistOfAttributesOfDescription.hasNext()){
                                Attribute currentAttributeDescription = (Attribute)ilistOfAttributesOfDescription.next();
								
                                if(currentAttributeDescription.getName().equals("label")){
                                    nameNode = currentAttributeDescription.getValue();
                                }
                            }
                        }
						
                        if(currentChildNode.toString().equals("[Element: <position/>]")){
                            position = currentChildNode.getValue();
                        }
						
                        if(currentChildNode.toString().equals("[Element: <form/>]")){
                            List listOfAttributesOfForm = currentChildNode.getAttributes();
                            Iterator ilistOfAttributesOfForm = listOfAttributesOfForm.iterator();
                            while(ilistOfAttributesOfForm.hasNext()){
                                Attribute currentAttributeDescription = (Attribute)ilistOfAttributesOfForm.next();
								
                                if(currentAttributeDescription.getName().equals("outlineColor")){
                                    outlineColor = currentAttributeDescription.getValue();
                                }
                                if(currentAttributeDescription.getName().equals("forme")){
                                    forme = currentAttributeDescription.getValue();
                                }
                                if(currentAttributeDescription.getName().equals("image")){
                                    image = currentAttributeDescription.getValue();
                                }
                                if(currentAttributeDescription.getName().equals("fillColor")){
                                    fillColor = currentAttributeDescription.getValue();
                                }
                            }
                        }
						
                    }
					
                    /* Assignement of default values*/
					
                    idNode = currentNode.getAttributeValue("id");
					
                    bw.write("\tnode [");
                    bw.newLine();
                    bw.write("\t\tid "+idNode);
                    bw.newLine();
                    if(!nameNode.equals("")){
                        bw.write("\t\tname \""+nameNode+"\"");
                        bw.newLine();
                    }
                    if(x!=0.0){
                        bw.write("\t\tgraphics [");
                        bw.newLine();
                        if(!position.equals("")){
                            bw.write("\t\t\t"+position+" [");
                            bw.newLine();
                            bw.write("\t\t\t\t x "+x);
                            bw.newLine();
                            bw.write("\t\t\t\t y "+y);
                            bw.newLine();
                            if(z!=0){
                                bw.write("\t\t\t\t z "+z);
                                bw.newLine();
                            }
                            if(w!=0){
                                bw.write("\t\t\t\t w "+w);
                                bw.newLine();                                
                            }
                            if(h!=0){
                                bw.write("\t\t\t\t h "+h);
                                bw.newLine();                                
                            }
                            if(d!=0){
                                bw.write("\t\t\t\t d "+d);
                                bw.newLine();
                            }
                            if(!image.equals("")){
                                bw.write("\t\t\t\t image "+image);
                                bw.newLine();
                            }
                            if(!outlineColor.equals("")){
                                bw.write("\t\t\t\t outlineColor "+outlineColor);
                                bw.newLine();
                            }
                            if(!forme.equals("")){
                                bw.write("\t\t\t\t forme "+forme);
                                bw.newLine();
                            }
                            if(!fillColor.equals("")){
                                bw.write("\t\t\t\t fillColor "+fillColor);
                                bw.newLine();
                            }
                            bw.write("\t\t\t]");
                            bw.newLine();
                        }
                        else{
                            bw.write("\t\t\t x "+x);
                            bw.newLine();
                            bw.write("\t\t\t y "+y);
                            bw.newLine();
                            if(z!=0){
                                bw.write("\t\t\t z "+z);
                                bw.newLine();
                            }
                            if(w!=0){
                                bw.write("\t\t\t w "+w);
                                bw.newLine();
                            }
                            if(h!=0){
                                bw.write("\t\t\t h "+h);
                                bw.newLine();
                            }
                            if(d!=0){
                                bw.write("\t\t\t d "+d);
                                bw.newLine();
                            }
                            if(!image.equals("")){
                                bw.write("\t\t\t image "+image);
                                bw.newLine();
                            }
                            if(!outlineColor.equals("")){
                                bw.write("\t\t\t outlineColor "+outlineColor);
                                bw.newLine();
                            }
                            if(!forme.equals("")){
                                bw.write("\t\t\t forme "+forme);
                                bw.newLine();
                            }
                            if(!fillColor.equals("")){
                                bw.write("\t\t\t fillColor "+fillColor);
                                bw.newLine();
                            }
                        }
                        bw.write("\t\t]");
                        bw.newLine();
                    }
                    bw.write("\t]");
                    bw.newLine();
                }
				
				
                /* Links */
				
				
                String srcNode="", tgtNode="", bandwidth="", metric="", linkType="";
				
				
                List listOfLink = links.getChildren();
                Iterator ilistOfLink = listOfLink.iterator();
                while(ilistOfLink.hasNext()){
                    Element currentLink = (Element)ilistOfLink.next();
					
                    List listOfChildOfLink = currentLink.getChildren();
                    Iterator ilistOfChildOfLink = listOfChildOfLink.iterator();
                    while(ilistOfChildOfLink.hasNext()){
                        Element currentChildLink = (Element)ilistOfChildOfLink.next();
						
                        if(currentChildLink.toString().equals("[Element: <source/>]")){
                            List listOfAttributeSource = currentChildLink.getAttributes();
                            Iterator ilistOfAttributeSource = listOfAttributeSource.iterator();
                            while(ilistOfAttributeSource.hasNext()){
                                Attribute currentAttributeSource = (Attribute)ilistOfAttributeSource.next();
								
                                if(currentAttributeSource.getName().equals("node")){
                                    srcNode = currentAttributeSource.getValue();
                                }
                            }
                        }
						
                        if(currentChildLink.toString().equals("[Element: <target/>]")){
                            List listOfAttributeTarget = currentChildLink.getAttributes();
                            Iterator ilistOfAttributeTarget = listOfAttributeTarget.iterator();
                            while(ilistOfAttributeTarget.hasNext()){
                                Attribute currentAttributeTarget = (Attribute)ilistOfAttributeTarget.next();
								
                                if(currentAttributeTarget.getName().equals("node")){
                                    tgtNode = currentAttributeTarget.getValue();
                                }
                            }
                        }
						
                        if(currentChildLink.toString().equals("[Element: <bandwidth/>]")){
                            bandwidth = currentChildLink.getValue();
                        }
						
                        if(currentChildLink.toString().equals("[Element: <metric/>]")){
                            metric = currentChildLink.getValue();
                        }
						
                        if(currentChildLink.toString().equals("[Element: <linkType/>]")){
                            List listOfAttributesOfType = currentChildLink.getAttributes();
                            Iterator ilistOfAttributesOfType = listOfAttributesOfType.iterator();
                            while(ilistOfAttributesOfType.hasNext()){
                                Attribute currentAttributeType = (Attribute)ilistOfAttributesOfType.next();
								
                                if(currentAttributeType.getName().equals("type1")){
                                    if(currentAttributeType.getValue().equals("simplex")){
                                        linkType="1";
                                    }
                                    else{
                                        linkType="0";
                                    }
                                }
                            }
                        }
                    }
					
                    /* Assignement of default values*/
                    if(bandwidth.equals("")){
                        bandwidth=defaultValue_Link_bandwidth;
                    }
                    if(linkType.equals("")){
                        linkType=defaultValue_Link_linkType;
                    }
                    if(metric.equals("")){
                        metric=defaultValue_Link_metric;
                    }
					
                    bw.write("\tedge [");
                    bw.newLine();
                    bw.write("\t\tsimplex "+linkType);
                    bw.newLine();
                    bw.write("\t\tsource "+srcNode);
                    bw.newLine();
                    bw.write("\t\ttarget "+tgtNode);
                    bw.newLine();
                    bw.write("\t\tbandwidth "+bandwidth);
                    bw.newLine();
                    bw.write("\t\tmetric "+metric);
                    bw.newLine();
                    bw.write("\t]");
                    bw.newLine();
                }
				
                bw.write("]");
                bw.newLine();
            }
            bw.close();
            fw.close();
			result.add("ParserToGML","Export succeeded");
			
		} catch (Exception e) {
			e.printStackTrace();
			result.add("ParserToGML","Export had problems "+e);
		}
    }
}
